|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00016 #include "derivative.h" 00017 #include "edma.h" 00018 /* 00019 ****************************************************************************** 00020 * Constants 00021 ****************************************************************************** 00022 */ 00025 const uint32_t cu32DMACopyArrayTCD[] = 00026 { 00027 (uint32_t)CLEAR, 00028 (DMA_8_BIT_SOURCE | DMA_8_BIT_TARGET | DMA_OFFSET(1u)), 00029 (uint32_t)CLEAR, 00030 (uint32_t)CLEAR, 00031 (uint32_t)CLEAR, 00032 (CHANNEL_TO_CHANNEL_LINKING_ON_MINOR_LOOP_DIS | CURRENT_MAJOR_ITERATION(1u) 00033 | DMA_OFFSET(1u)), 00034 (uint32_t)CLEAR, 00035 (CHANNEL_TO_CHANNEL_LINKING_ON_MAJOR_LOOP_DIS 00036 | NUMBER_OF_MAJOR_ITERATIONS(1u) | DONT_STALL_DMA | DMA_ISR_WHEN_DONE) }; 00037 /* 00038 ****************************************************************************** 00039 * Globals 00040 ****************************************************************************** 00041 */ 00042 /* 00043 ****************************************************************************** 00044 * vfnDMASet 00045 ****************************************************************************** 00046 */ 00047 void vfnDMASet(uint8_t u8Chan, uint8_t *pu8DestAddr, uint8_t *pu8SourceAddr, 00048 uint16_t u16NOfBytes) 00049 { 00050 /* clear done flag */ 00051 EDMA.CDSBR.R = u8Chan; 00052 /* copy bytes to buffer -> use DMA */ 00053 EDMA.TCD[u8Chan].CITER = u16NOfBytes; 00054 EDMA.TCD[u8Chan].BITER = u16NOfBytes; 00055 /* set destination */ 00056 EDMA.TCD[u8Chan].DADDR = (uint32_t)pu8DestAddr; 00057 /* set source */ 00058 EDMA.TCD[u8Chan].SADDR = (uint32_t)pu8SourceAddr; 00059 00060 return; 00061 } 00062 /* 00063 ****************************************************************************** 00064 * vfnDMAConfig 00065 ****************************************************************************** 00066 */ 00067 void vfnDMAConfig(TCD_t *ptMyTCD, uint8_t u8Channel) 00068 { 00069 /* Configure DMA Channel TCD */ 00070 EDMA.TCD[u8Channel].SADDR = ptMyTCD->P.SADDR; 00071 EDMA.TCD[u8Channel].SMOD = ptMyTCD->P.SMOD; 00072 EDMA.TCD[u8Channel].SSIZE = ptMyTCD->P.SSIZE; 00073 EDMA.TCD[u8Channel].DMOD = ptMyTCD->P.DMOD; 00074 EDMA.TCD[u8Channel].DSIZE = ptMyTCD->P.DSIZE; 00075 EDMA.TCD[u8Channel].SOFF = ptMyTCD->P.SOFF; 00076 EDMA.TCD[u8Channel].NBYTES = ptMyTCD->P.NBYTES; 00077 EDMA.TCD[u8Channel].SLAST = ptMyTCD->P.SLAST; 00078 EDMA.TCD[u8Channel].DADDR = ptMyTCD->P.DADDR; 00079 EDMA.TCD[u8Channel].CITERE_LINK = ptMyTCD->P.CITERE_LINK; 00080 EDMA.TCD[u8Channel].CITER = ptMyTCD->P.CITER; 00081 EDMA.TCD[u8Channel].DOFF = ptMyTCD->P.DOFF; 00082 EDMA.TCD[u8Channel].DLAST_SGA = ptMyTCD->P.DLAST_SGA; 00083 EDMA.TCD[u8Channel].BITERE_LINK = ptMyTCD->P.BITERE_LINK; 00084 EDMA.TCD[u8Channel].BITER = ptMyTCD->P.BITER; 00085 EDMA.TCD[u8Channel].BWC = ptMyTCD->P.BWC; 00086 EDMA.TCD[u8Channel].MAJORLINKCH = ptMyTCD->P.MAJORLINKCH; 00087 EDMA.TCD[u8Channel].DONE = ptMyTCD->P.DONE; 00088 EDMA.TCD[u8Channel].ACTIVE = ptMyTCD->P.ACTIVE; 00089 EDMA.TCD[u8Channel].MAJORE_LINK = ptMyTCD->P.MAJORE_LINK; 00090 EDMA.TCD[u8Channel].E_SG = ptMyTCD->P.E_SG; 00091 EDMA.TCD[u8Channel].D_REQ = ptMyTCD->P.D_REQ; 00092 EDMA.TCD[u8Channel].INT_HALF = ptMyTCD->P.INT_HALF; 00093 EDMA.TCD[u8Channel].INT_MAJ = ptMyTCD->P.INT_MAJ; 00094 EDMA.TCD[u8Channel].START = ptMyTCD->P.START; 00095 00096 return; 00097 } 00098 /* 00099 ****************************************************************************** 00100 * vfnDMAStart 00101 ****************************************************************************** 00102 */ 00103 void vfnDMAStart(const uint8_t u8Chan) 00104 { 00105 /* Clear any "Done flags */ 00106 EDMA.TCD[u8Chan].DONE = CLEAR; 00107 /* start dma channel */ 00108 EDMA.TCD[u8Chan].START = TRUE; 00109 00110 return; 00111 } 00112 /* 00113 ****************************************************************************** 00114 * vfnDMAEnable 00115 ****************************************************************************** 00116 */ 00117 void vfnDMAEnable(const uint8_t u8Chan) 00118 { 00119 /* enable dma channel */ 00120 EDMA.SERQR.R = u8Chan; 00121 00122 return; 00123 } 00124 /* 00125 ****************************************************************************** 00126 * u8fnDMAPending 00127 ****************************************************************************** 00128 */ 00129 uint8_t u8fnDMAPending(const uint8_t u8Chan) 00130 { 00131 return ((uint8_t)EDMA.TCD[u8Chan].DONE); 00132 } 00133 /* 00134 ****************************************************************************** 00135 * u8fnDMACopyArray 00136 ****************************************************************************** 00137 */ 00138 void vfnDMACopyArray(uint8_t* pu8Source, uint8_t* pu8Target, uint16_t u16Size, 00139 uint8_t u8Channel) 00140 { 00141 uint8_t u8Status; 00142 uint8_t u8Counter; 00143 TCD_t tMyConfig; 00144 00145 /* Init Local Variables */ 00146 u8Status = CLEAR; 00147 00148 /* Load defaults */ 00149 for(u8Counter = CLEAR; u8Counter < N_ELEMENTS(cu32DMACopyArrayTCD); u8Counter++) 00150 { 00151 tMyConfig.A.SETTINGS[u8Counter] = cu32DMACopyArrayTCD[u8Counter]; 00152 } 00153 00154 /* Load particular settings for this transfer */ 00155 tMyConfig.P.NBYTES = u16Size; 00156 tMyConfig.P.SADDR = (uint32_t)pu8Source; 00157 tMyConfig.P.DADDR = (uint32_t)pu8Target; 00158 00159 /* Load settings to DMA */ 00160 vfnDMAConfig((TCD_t*)&tMyConfig, u8Channel); 00161 00162 /* Enable the channel */ 00163 vfnDMAEnable(u8Channel); 00164 00165 /* Start the channel */ 00166 vfnDMAStart(u8Channel); 00167 00168 return; 00169 } 00170 /* 00171 ****************************************************************************** 00172 * vfnDMAPersonalizeChannel 00173 ****************************************************************************** 00174 */ 00175 //void vfnDMAPersonalizeChannel(const uint8_t u8DMAChannel, const uint16_t* pu16Destination, 00176 // const uint16_t* pu16Source, const uint16_t u16Size) 00177 //{ 00178 // /* Source address is the inbox + the offset */ 00179 // EDMA.TCD[u8DMAChannel].SADDR = (uint32_t)(pu16Source); 00180 // /* Destination address is our passed pointer */ 00181 // EDMA.TCD[u8DMAChannel].DADDR = (uint32_t)pu16Destination; 00182 // /* Number of bytes is given by the passed variable * 2 */ 00183 // /* (passed variable is in u16) */ 00184 // EDMA.TCD[u8DMAChannel].NBYTES = (uint32_t)(u16Size); 00185 // /* Allow HW linking to the next channel - reset after tx */ 00186 // EDMA.TCD[u8DMAChannel].MAJORE_LINK = TRUE; 00187 // 00188 // return; 00189 //} 00190 /* 00191 ****************************************************************************** 00192 * u8fnWaitForDMA 00193 ****************************************************************************** 00194 */ 00195 uint8_t u8fnWaitForDMA(uint8_t u8Channel) 00196 { 00197 uint8_t u8Status; 00198 uint16_t u16TimeOut; 00199 00200 /* Init locals */ 00201 u8Status = CLEAR; 00202 u16TimeOut = 0xFFFFu; 00203 00204 /* Wait for the Major Loop to be completed */ 00205 while((DMA_COMPLETED_MAJOR_LOOP != u8fnDMAReturnChannelStatus(u8Channel)) 00206 && u16TimeOut--) 00207 { 00208 /* Wait here */ 00209 }; 00210 00211 if(CLEAR == u16TimeOut) 00212 { 00213 /* We timed-out */ 00214 u8Status = TRUE; 00215 } 00216 else 00217 { 00218 /* Let's go */ 00219 } 00220 return (u8Status); 00221 } 00222 /* 00223 ****************************************************************************** 00224 * u8fnDMAReturnChannelStatus 00225 ****************************************************************************** 00226 */ 00227 uint8_t u8fnDMAReturnChannelStatus(uint8_t u8Channel) 00228 { 00229 /* Local variables */ 00230 uint8_t u8Status; 00231 00232 u8Status = CLEAR; 00233 00234 /* Based on the condition of START, Active and DONE, determine the state */ 00235 if(TRUE == EDMA.TCD[u8Channel].START) 00236 { 00237 u8Status = DMA_SERVICE_REQUEST_ASSERTED; 00238 } 00239 else 00240 { 00241 if(TRUE == EDMA.TCD[u8Channel].ACTIVE) 00242 { 00243 u8Status = DMA_EXECUTING; 00244 } 00245 else 00246 { 00247 if(TRUE == EDMA.TCD[u8Channel].DONE) 00248 { 00249 u8Status = DMA_COMPLETED_MAJOR_LOOP; 00250 } 00251 else 00252 { 00253 u8Status = DMA_COMPLETED_MINOR_LOOP; 00254 } 00255 } 00256 } 00257 00258 /* Return state */ 00259 return (u8Status); 00260 } 00261 /* 00262 ****************************************************************************** 00263 * vfnDMAMUXInit 00264 ****************************************************************************** 00265 */ 00266 void vfnDMAMUXInit(uint8_t u8DMACh, uint8_t u8DMAMuxSource, uint8_t u8Trigger, uint8_t u8Enable) 00267 { 00268 DMAMUX.CHCONFIG[u8DMACh].B.SOURCE = u8DMAMuxSource; 00269 DMAMUX.CHCONFIG[u8DMACh].B.TRIG = u8Trigger; 00270 DMAMUX.CHCONFIG[u8DMACh].B.ENBL = u8Enable; 00271 00272 return; 00273 } 00274 /* 00275 ****************************************************************************** 00276 * vfnDMAMuxEnable 00277 ****************************************************************************** 00278 */ 00279 void vfnDMAMuxEnable(uint8_t u8DMACh, uint8_t u8Enable) 00280 { 00281 DMAMUX.CHCONFIG[u8DMACh].B.ENBL = u8Enable; 00282 return; 00283 } 00284 /* 00285 ****************************************************************************** 00286 * u8fnDMAMuxChEnStatus 00287 ****************************************************************************** 00288 */ 00289 uint8_t u8fnDMAMuxChEnStatus(uint8_t u8DMACh) 00290 { 00291 return(DMAMUX.CHCONFIG[u8DMACh].B.ENBL); 00292 } 00293 /* 00294 ****************************************************************************** 00295 * 00296 * End of file. 00297 * 00298 ****************************************************************************** 00299 */